package cn.edu.hnu.matching.controller;

import cn.edu.hnu.matching.common.PageResult;
import cn.edu.hnu.matching.common.Result;
import cn.edu.hnu.matching.common.ResultCode;
import cn.edu.hnu.matching.exception.ThrowUtils;
import cn.edu.hnu.matching.model.dto.UserLogoutDto;
import cn.edu.hnu.matching.model.dto.UserModifyAvatarDto;
import cn.edu.hnu.matching.model.dto.UserModifyDescriptionDto;
import cn.edu.hnu.matching.model.dto.UserModifyTagsDto;
import cn.edu.hnu.matching.model.dto.UserRecommendationDto;
import cn.edu.hnu.matching.model.dto.UserSearchByKeywordDto;
import cn.edu.hnu.matching.model.vo.UserDetailVo;
import cn.edu.hnu.matching.model.vo.UserSearchVo;
import cn.edu.hnu.matching.model.vo.UserWxLoginVo;
import cn.edu.hnu.matching.service.IUserService;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author n70huihui
 * @since 2025-04-10
 */
@RestController
@RequestMapping("/user")
@Tag(name = "用户表相关接口")
@RequiredArgsConstructor
public class UserController {

    // 构造器依赖注入
    private final IUserService userService;

    @PostMapping("/wxlogin/{code}")
    @Operation(summary = "登录")
    public Result<UserWxLoginVo> wxlogin(@PathVariable String code) {
        ThrowUtils.throwIf(StrUtil.isBlank(code), ResultCode.PARAMS_ERROR, "登录码不能为空");
        return userService.wxlogin(code);
    }

    @DeleteMapping("/logout")
    @Operation(summary = "用户退出登录")
    public Result<Void> logout(@RequestBody UserLogoutDto userLogoutDto) {
        ThrowUtils.throwIf(userLogoutDto == null, ResultCode.PARAMS_ERROR);
        String openId = userLogoutDto.getOpenId();
        ThrowUtils.throwIf(StrUtil.isBlank(openId), ResultCode.PARAMS_ERROR);
        return userService.logout(openId);
    }

    @PutMapping("/modifyAvatar")
    @Operation(summary = "修改个人头像")
    public Result<Void> modifyAvatar(@RequestBody @Validated UserModifyAvatarDto userModifyAvatarDto) {
        ThrowUtils.throwIf(userModifyAvatarDto == null, ResultCode.PARAMS_ERROR);
        return userService.modifyAvatar(userModifyAvatarDto);
    }

    @PutMapping("/modifyUserName/{userName}")
    @Operation(summary = "修改用户名")
    public Result<Void> modifyUserName(@PathVariable String userName) {
        ThrowUtils.throwIf(StrUtil.isBlank(userName), ResultCode.PARAMS_ERROR, "用户名不能为空");
        ThrowUtils.throwIf(userName.length() > 20, ResultCode.PARAMS_ERROR, "用户名不能超过20个字符");
        return userService.modifyUserName(userName);
    }

    @PutMapping("/modifyGender/{gender}")
    @Operation(summary = "修改用户性别")
    public Result<Void> modifyGender(@PathVariable String gender) {
        ThrowUtils.throwIf(gender == null, ResultCode.PARAMS_ERROR);
        ThrowUtils.throwIf(!StrUtil.isNumeric(gender), ResultCode.PARAMS_ERROR, "参数有非法字符");
        short genderId = Short.parseShort(gender);
        ThrowUtils.throwIf((genderId != 0 && genderId != 1), ResultCode.PARAMS_ERROR, "错误的性别");
        return userService.modifyGender(genderId);
    }

    @PutMapping("/modifyDescription")
    @Operation(summary = "修改用户个人简介")
    public Result<Void> modifyDescription(@RequestBody UserModifyDescriptionDto userModifyDescriptionDto) {
        ThrowUtils.throwIf(userModifyDescriptionDto == null, ResultCode.PARAMS_ERROR);
        String description = userModifyDescriptionDto.getDescription();
        ThrowUtils.throwIf(StrUtil.isBlank(description), ResultCode.PARAMS_ERROR, "个人简介不能为空");
        ThrowUtils.throwIf(description.length() > 512, ResultCode.PARAMS_ERROR, "个人简介不得超过512个字符");
        return userService.modifyDescription(description);
    }

    @PutMapping("/modifyWeChatId/{weChatId}")
    @Operation(summary = "修改用户微信号")
    public Result<Void> modifyWeChatId(@PathVariable String weChatId) {
        ThrowUtils.throwIf(StrUtil.isBlank(weChatId), ResultCode.PARAMS_ERROR);
        return userService.modifyWeChatId(weChatId);
    }

    @PutMapping("/modifyQQId/{qqId}")
    @Operation(summary = "修改用户QQ号")
    public Result<Void> modifyQQId(@PathVariable String qqId) {
        ThrowUtils.throwIf(qqId == null, ResultCode.PARAMS_ERROR);
        ThrowUtils.throwIf(!StrUtil.isNumeric(qqId), ResultCode.PARAMS_ERROR, "QQ号不能有特殊字符");
        return userService.modifyQQId(qqId);
    }

    @PutMapping("/modifyTags")
    @Operation(summary = "修改用户标签")
    public Result<Void> modifyTags(@RequestBody UserModifyTagsDto userModifyTagsDto) {
        ThrowUtils.throwIf(userModifyTagsDto == null, ResultCode.PARAMS_ERROR);
        List<String> tags = userModifyTagsDto.getTags();
        ThrowUtils.throwIf(ObjectUtil.isEmpty(tags), ResultCode.PARAMS_ERROR, "标签不能为空");
        ThrowUtils.throwIf(tags.size() > 10, ResultCode.PARAMS_ERROR, "标签数量不能超过10个");
        return userService.modifyTags(tags);
    }

    @GetMapping("/recommend")
    @Operation(summary = "获取用户首页推荐")
    public Result<List<UserSearchVo>> getHomepageRecommendation(UserRecommendationDto recommendationDto) {
        ThrowUtils.throwIf(recommendationDto == null, ResultCode.PARAMS_ERROR);
        String tags = recommendationDto.getTags();
        List<String> tagsList = JSONUtil.parseArray(tags).toList(String.class);
        return userService.getHomepageRecommendation(tagsList);
    }

    @GetMapping("/getDetail/{id}")
    @Operation(summary = "根据id查询用户详细信息")
    public Result<UserDetailVo> getUserDetailById(@PathVariable Long id) {
        ThrowUtils.throwIf(id == null, ResultCode.PARAMS_ERROR);
        return userService.getUserDetailById(id);
    }

    @GetMapping("/search")
    @Operation(summary = "根据关键词搜索")
    public Result<PageResult<UserSearchVo>> searchUserByKeyword(UserSearchByKeywordDto userSearchByKeywordDto) {
        ThrowUtils.throwIf(userSearchByKeywordDto == null, ResultCode.PARAMS_ERROR);
        String keyword = userSearchByKeywordDto.getKeyword();
        ThrowUtils.throwIf(StrUtil.isBlank(keyword), ResultCode.PARAMS_ERROR, "搜索词不能为空");
        return userService.searchUserByKeyword(userSearchByKeywordDto);
    }
}
